package org.jsola.hr.service.impl;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.jsola.core.Page;
import org.jsola.core.entity.BaseDO;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IDepInfoDAO;
import org.jsola.hr.dao.IEmpInfoDAO;
import org.jsola.hr.dao.IPositionInfoDAO;
import org.jsola.hr.dto.PositionInfoAddDTO;
import org.jsola.hr.dto.PositionInfoUpdateDTO;
import org.jsola.hr.entity.DepInfoDO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.entity.EmpPositionDO;
import org.jsola.hr.entity.PositionInfoDO;
import org.jsola.hr.query.PositionInfoQuery;
import org.jsola.hr.service.IEmpInfoService;
import org.jsola.hr.service.IEmpPositionService;
import org.jsola.hr.service.IPositionInfoService;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhr
 */
@Service("hrPositionInfoServiceImpl")
public class PositionInfoServiceImpl implements IPositionInfoService {

    @Autowired
    private IPositionInfoDAO positionInfoDAO;

    @Autowired
    private IDepInfoDAO depInfoDAO;

    @Autowired
    private IEmpInfoDAO empInfoDAO;

    @Autowired
    private IEmpInfoService empInfoService;

    @Autowired
    @Lazy
    private IEmpPositionService empPositionService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public PositionInfoVO save(PositionInfoAddDTO positionInfoAddDTO, TokenUser tokenUser) {
        // 转DO
        PositionInfoDO positionInfoDO = positionInfoAddDTO.to(PositionInfoDO.class);

        // 校验岗位编码
        checkPositionCode(positionInfoDO.getId(), positionInfoDO.getCode(), positionInfoDO.getCompanyId(), tokenUser.getSiteId());
        // 校验岗位名称
        checkPositionName(positionInfoDO.getId(), positionInfoDO.getName(), positionInfoDO.getCompanyId(), positionInfoDO.getParentId(), tokenUser.getSiteId());
        // 校验父岗位
        checkParent(positionInfoDO.getParentId(), tokenUser.getSiteId());
        // 保存
        positionInfoDO = save(positionInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return positionInfoDO.to(PositionInfoVO.class);
    }

    /**
     * 校验父岗位
     *
     * @param parentId 父岗位id
     * @param siteId   站点
     */
    private void checkParent(String parentId, String siteId) {
        if (StringUtils.isEmpty(parentId) || "0".equals(parentId)) {
            return;
        }
        PositionInfoDO positionInfoDO = selectDOById(parentId, siteId);
        ParamException.notNull(positionInfoDO, "岗位的父级不存在");
    }

    /**
     * 校验岗位code
     *
     * @param id        id
     * @param code      岗位编码
     * @param companyId 公司id
     * @param siteId    站点
     */
    private void checkPositionCode(String id, String code, String companyId, String siteId) {
        if (StringUtils.isEmpty(code)) {
            return;
        }
        if (StringUtils.isEmpty(companyId)) {
            return;
        }
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("code", code)
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        PositionInfoDO positionInfo = positionInfoDAO.selectOneByExample(example);
        if (Objects.nonNull(positionInfo)) {
            if (StringUtils.isEmpty(id) || !id.equals(positionInfo.getId())) {
                throw new ParamException("岗位编码已存在");
            }
        }
    }

    /**
     * 校验岗位名称
     *
     * @param id        id
     * @param name      岗位名称
     * @param companyId 公司id
     * @param siteId    站点
     */
    private void checkPositionName(String id, String name, String companyId, String parentId, String siteId) {
        if (StringUtils.isEmpty(name)) {
            return;
        }
        if (StringUtils.isEmpty(companyId)) {
            return;
        }
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("name", name)
                .andEqualTo("parentId", parentId)
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        PositionInfoDO positionInfo = positionInfoDAO.selectOneByExample(example);
        if (Objects.nonNull(positionInfo)) {
            if (StringUtils.isEmpty(id) || !id.equals(positionInfo.getId())) {
                throw new ParamException("岗位名称已存在");
            }
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(PositionInfoUpdateDTO positionInfoUpdateDTO, TokenUser tokenUser) {
        //转DO
        PositionInfoDO positionInfoDO = positionInfoUpdateDTO.to(PositionInfoDO.class);

        // 校验岗位编码
        checkPositionCode(positionInfoDO.getId(), positionInfoDO.getCode(), positionInfoDO.getCompanyId(), tokenUser.getSiteId());
        // 校验岗位名称
        checkPositionName(positionInfoDO.getId(), positionInfoDO.getName(), positionInfoDO.getCompanyId(), positionInfoDO.getParentId(), tokenUser.getSiteId());
        // 校验父岗位
        checkParent(positionInfoDO.getParentId(), tokenUser.getSiteId());

        //根据主键更新，只更新非null值
        return updateByIdSelective(positionInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... positionInfoIds) {
        if (positionInfoIds == null || positionInfoIds.length == 0) {
            return 0;
        }
        for (String positionId : positionInfoIds) {
            PositionInfoDO positionInfoDO = selectDOById(positionId, tokenUser.getSiteId());
            if (Objects.isNull(positionInfoDO)) {
                continue;
            }
            if (positionInfoDO.getType() == 2) {
                // 岗位分类
                List<PositionInfoListVO> positionInfoList = listChildPositionByParent(positionId, 1, tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(positionInfoList)) {
                    throw new ParamException("岗位类型'" + positionInfoDO.getName() + "'下还存在岗位,请先处理");
                }
            } else {
                List<EmpInfoListVO> empInfoList = empInfoService.listAllVoByPositionId(positionInfoDO.getCompanyId(), tokenUser, positionId);
                if (!CollectionUtils.isEmpty(empInfoList)) {
                    throw new ParamException("还有岗位是'" + positionInfoDO.getName() + "'的员工,请先处理");
                }
            }
        }

        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) positionInfoIds);
    }


    @Override
    public PositionInfoVO selectById(String positionInfoId, String siteId) {
        PositionInfoDO positionInfoDO = selectDOById(positionInfoId, siteId);
        if (positionInfoDO == null) {
            return null;
        }
        return positionInfoDO.to(PositionInfoVO.class);
    }

    @Override
    public PositionInfoVO selectByIdWhetherDel(String positionInfoId, String siteId) {
        if (positionInfoId == null) {
            return null;
        }
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("id", positionInfoId);
        PositionInfoDO positionInfoDO = positionInfoDAO.selectOneByExample(example);
        if (positionInfoDO != null) {
            return positionInfoDO.to(PositionInfoVO.class);
        }
        return null;
    }

    @Override
    public List<PositionInfoListVO> select(PositionInfoQuery positionInfoQuery, String siteId) {
        List<PositionInfoDO> positionInfoDOList = selectDO(positionInfoQuery, siteId);
        return getVoListByDoList(positionInfoDOList);
    }

    /**
     * 根据doList获取voList
     *
     * @param doList do
     * @return vo
     */
    private List<PositionInfoListVO> getVoListByDoList(List<PositionInfoDO> doList) {
        if (CollectionUtils.isEmpty(doList)) {
            return doList == null ? null : new ArrayList<>();
        }
        return doList.stream()
                .map(positionInfoDO -> positionInfoDO.to(PositionInfoListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(PositionInfoQuery positionInfoQuery, String siteId) {
        Example example = buildExample(positionInfoQuery, siteId);
        return positionInfoDAO.selectCountByExample(example);
    }

    @Override
    public Page<PositionInfoListVO> selectPage(PositionInfoQuery positionInfoQuery, String siteId) {
        Example example = buildExample(positionInfoQuery, siteId);
        Page<PositionInfoDO> page = positionInfoDAO.selectPageByExample(example,
                positionInfoQuery.getPageNo(),
                positionInfoQuery.getPageSize());

        return page.to(PositionInfoListVO.class);
    }

    @Override
    public Page<PositionInfoListVO> selectPositionInfoListPage(PositionInfoQuery positionInfoQuery, TokenUser tokenUser) {
        // 查询公司下岗位类型 没有就创建
        createDefaultPositionInfo(positionInfoQuery.getCompanyId(), tokenUser);
        // 转vo
        Page<PositionInfoListVO> voPage = selectPage(positionInfoQuery, tokenUser.getSiteId());
        // 获取岗位的员工
        if (CollectionUtils.isEmpty(voPage.getEntities())) {
            return voPage;
        }
        voPage.getEntities().forEach(positionInfo -> {
            // 获取当前岗位及当前岗位的所有下级岗位
            List<PositionInfoDO> allPositionList = listAllAndChild(tokenUser.getSiteId(), positionInfo.getId());
            if (!CollectionUtils.isEmpty(allPositionList)) {
                String[] allPositionIds = allPositionList.stream().map(PositionInfoDO::getId).toArray(String[]::new);
                // 员工岗位对应关系
                List<EmpPositionDO> empPositionDOList = empPositionService
                        .listAllByPositionId(positionInfoQuery.getCompanyId(), tokenUser.getSiteId(), allPositionIds);
                // 查询当前岗位及子岗位下所有员工
                if (CollectionUtils.isEmpty(empPositionDOList)) {
                    positionInfo.setEmpChildrenCount(0);
                    positionInfo.setEmpDirectCount(0);
                    positionInfo.setEmpChildrenList(null);
                    positionInfo.setEmpDirectList(null);
                } else {
                    // 岗位及子岗位的员工信息
                    List<String> empIds = empPositionDOList.parallelStream().map(EmpPositionDO::getEmpId).distinct().collect(Collectors.toList());
                    // 当前岗位及子岗位的
                    List<EmpInfoDO> empInfoDOList = empInfoService.selectOnJobDoByIds(empIds);
                    positionInfo.setEmpChildrenCount(empInfoDOList.size());
                    positionInfo.setEmpChildrenList(empInfoDOList.parallelStream().map(empInfoDO
                            -> empInfoDO.to(EmpInfoListVO.class)).collect(Collectors.toList()));

                    // 当前岗位的
                    List<String> empDirectIds = empPositionDOList.parallelStream().filter(empPositionDO
                            -> positionInfo.getId().equals(empPositionDO.getPositionId()))
                            .map(EmpPositionDO::getEmpId).distinct().collect(Collectors.toList());
                    List<EmpInfoDO> empDirectInfoList = empInfoService.selectOnJobDoByIds(empDirectIds);
                    positionInfo.setEmpDirectCount(empDirectInfoList.size());
                    positionInfo.setEmpDirectList(empDirectInfoList.parallelStream().map(empInfoDO
                            -> empInfoDO.to(EmpInfoListVO.class)).collect(Collectors.toList()));
                }
            }
        });
        return voPage;
    }


    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void createDefaultPositionInfo(String companyId, TokenUser tokenUser) {
        // 询公司下岗位类型 没有就创建
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("level", 2)
                .andEqualTo("type",2)
                .andEqualTo("valid", true);
        int count = positionInfoDAO.selectCountByExample(example);
        // 没有岗位类型则创建
        if (count > 0) {
            return;
        }
        PositionInfoAddDTO positionInfoAddDTO = new PositionInfoAddDTO();
        positionInfoAddDTO.setCompanyId(companyId);
        positionInfoAddDTO.setName("默认类型");
        positionInfoAddDTO.setLevel(2);
        positionInfoAddDTO.setParentId(selectParentPositionId(companyId, tokenUser).getId());
        positionInfoAddDTO.setSort(0);
        positionInfoAddDTO.setType(2);
        save(positionInfoAddDTO, tokenUser);
    }

    @Override
    public PositionInfoDO selectDOById(String positionInfoId, String siteId) {
        return listById(positionInfoId, siteId);
    }

    @Override
    public List<PositionInfoDO> selectDO(PositionInfoQuery positionInfoQuery, String siteId) {
        Example example = buildExample(positionInfoQuery, siteId);
        return positionInfoDAO.selectByExample(example);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param positionInfoQuery 查询参数
     * @param siteId            所属站点id
     * @return example
     */
    private Example buildExample(PositionInfoQuery positionInfoQuery, String siteId) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (positionInfoQuery.getType() != null) {
            example.and().andEqualTo("type", positionInfoQuery.getType());
        }
        if (positionInfoQuery.getName() != null) {
            example.and().andLike("name", "%" + positionInfoQuery.getName() + "%");
        }
        if (positionInfoQuery.getCode() != null) {
            example.and().andLike("code", "%" + positionInfoQuery.getCode() + "%");
        }
        if (positionInfoQuery.getRemark() != null) {
            example.and().andLike("remark", "%" + positionInfoQuery.getRemark() + "%");
        }
        if (positionInfoQuery.getDesc() != null) {
            example.and().andLike("desc", "%" + positionInfoQuery.getDesc() + "%");
        }
        if (positionInfoQuery.getFormalNum() != null) {
            example.and().andEqualTo("formalNum", positionInfoQuery.getFormalNum());
        }
        if (positionInfoQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", positionInfoQuery.getCompanyId());
        }
        if (positionInfoQuery.getGmtCreateStart() != null &&
                positionInfoQuery.getGmtCreateEnd() != null) {
            example.and().andBetween("gmtCreate", positionInfoQuery.getGmtCreateStart(),
                    positionInfoQuery.getGmtCreateEnd());
        }
        if (positionInfoQuery.getCreateUserId() != null) {
            example.and().andLike("createUserId", "%" + positionInfoQuery.getCreateUserId() + "%");
        }
        if (positionInfoQuery.getGmtModifiedStart() != null &&
                positionInfoQuery.getGmtModifiedEnd() != null) {
            example.and().andBetween("gmtModified", positionInfoQuery.getGmtModifiedStart(),
                    positionInfoQuery.getGmtModifiedEnd());
        }
        if (positionInfoQuery.getModifiedUserId() != null) {
            example.and().andLike("modifiedUserId", "%" + positionInfoQuery.getModifiedUserId() + "%");
        }
        if (positionInfoQuery.getLevel() != null) {
            example.and().andEqualTo("level", positionInfoQuery.getLevel());
        }
        if (positionInfoQuery.getSort() != null) {
            example.and().andEqualTo("sort", positionInfoQuery.getSort());
        }
        if (positionInfoQuery.getParentId() != null) {
            example.and().andEqualTo("parentId", positionInfoQuery.getParentId());
        }
        // 排序
        ExampleKit.setExampleOrder(example, positionInfoQuery.getOrders());
        return example;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public List<PositionInfoListVO> listTree(PositionInfoQuery positionInfoQuery, TokenUser tokenUser) {
        createDefaultPositionInfo(positionInfoQuery.getCompanyId(), tokenUser);
        return buildPositionTree(positionInfoDAO.selectListWithChildren(tokenUser.getSiteId()
                , positionInfoQuery.getCompanyId()), "0");
    }

    /**
     * 构建组织树
     *
     * @param positionInfoDOList 组织列表
     * @param parentId           父id，用于递归
     * @return 组织DTO列表
     */
    private List<PositionInfoListVO> buildPositionTree(List<PositionInfoVO> positionInfoDOList, String parentId) {
        List<PositionInfoListVO> groupListDTOList = Lists.newArrayList();
        for (PositionInfoVO positionInfoVO : positionInfoDOList) {
            if (positionInfoVO.getParentId().equals(parentId)) {
                PositionInfoListVO positionInfoListVO = positionInfoVO.to(PositionInfoListVO.class);
                positionInfoListVO.setChildCount(0);
                positionInfoListVO.setHasChild(Objects.nonNull(positionInfoVO.getHasChildCount()));
                groupListDTOList.add(positionInfoListVO);
                if (positionInfoListVO.getHasChild()) {
                    //将父id为此部门的放到子部门列表
                    positionInfoListVO.setPositionChildList(buildPositionTree(positionInfoDOList, positionInfoVO.getId()));
                }
            }
        }
        // 组织类型按创建时间排序 先创建的在前面
        groupListDTOList = groupListDTOList.stream()
                .sorted(Comparator.comparing(PositionInfoListVO::getGmtCreate))
                .collect(Collectors.toList());
        return groupListDTOList;
    }

    @Override
    public PositionInfoDO selectByNameAndLevel(String name, Integer level, String parentId, String companyId, TokenUser tokenUser) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andEqualTo("level", level)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if (name != null) {
            example.and().andEqualTo("name", name);
        }
        if (parentId != null) {
            example.and().andEqualTo("parentId", parentId);
        }
        List<PositionInfoDO> positionInfoDOList = positionInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(positionInfoDOList)) {
            return null;
        }
        return positionInfoDOList.get(0);
    }

    @Override
    public EmpAllInfoVO selectByEmpId(String empInfoId, String siteId) {
        EmpInfoDO empInfoDO = empInfoDAO.selectByPrimaryKey(empInfoId);
        EmpAllInfoVO empInfoVO = empInfoDO.to(EmpAllInfoVO.class);

        // 部门
        List<DepInfoDO> depInfoList = depInfoDAO.selectListByEmpId(empInfoVO.getId(), siteId);
        if (!CollectionUtils.isEmpty(depInfoList)) {
            String depNames = "";
            List<DepInfoVO> depInfoVoList = new ArrayList<>();

            for (DepInfoDO depInfo : depInfoList) {
                depNames = StringUtils.isEmpty(depNames) ? depInfo.getName() : (depNames + "," + depInfo.getName());

                DepInfoVO depInfoVO = depInfo.to(DepInfoVO.class);
                depInfoVoList.add(depInfoVO);
            }
            empInfoVO.setDepName(depNames);
            empInfoVO.setDepInfoList(depInfoVoList);
        }
        // 岗位
        List<PositionInfoDO> positionInfoList = positionInfoDAO.selectListByEmpId(empInfoVO.getId(), siteId);
        if (!CollectionUtils.isEmpty(positionInfoList)) {
            String positionNames = "";
            List<PositionInfoVO> positionInfoVoList = new ArrayList<>();

            for (PositionInfoDO positionInfo : positionInfoList) {
                positionNames = StringUtils.isEmpty(positionNames) ? positionInfo.getName() : (positionNames + "," + positionInfo.getName());

                PositionInfoVO positionInfoVO = positionInfo.to(PositionInfoVO.class);
                positionInfoVoList.add(positionInfoVO);
            }
            empInfoVO.setPositionName(positionNames);
            empInfoVO.setPositionInfoList(positionInfoVoList);
        }

        return empInfoVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void deleteByCompanyId(String companyId, TokenUser tokenUser) {
        List<PositionInfoDO> list = listByCompanyId(companyId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        String[] ids = list.stream()
                .map(BaseDO::getId).toArray(String[]::new);
        deleteByIds(tokenUser, ids);
    }

    /**
     * 获取公司下所有岗位
     *
     * @param companyId 岗位
     * @param siteId    站点id
     * @return 公司下所有岗位
     */
    @Override
    public List<PositionInfoDO> listByCompanyId(String companyId, String siteId) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        example.orderBy("gmtCreate").desc();
        List<PositionInfoDO> positionList = positionInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(positionList)) {
            positionList = new ArrayList<>();
        }
        return positionList;
    }

    @Override
    public PositionInfoDO selectParentPositionId(String companyId, TokenUser tokenUser) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("level", 1);
        return positionInfoDAO.selectOneByExample(example);
    }

    @Override
    public List<PositionInfoDO> listAllAndChild(String siteId, String... positionIds) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andIn("id", Arrays.asList(positionIds))
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        List<PositionInfoDO> positionInfoList = positionInfoDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(positionInfoList)) {
            List<String> idList = positionInfoList.stream().map(PositionInfoDO::getId).collect(Collectors.toList());
            getAllChildList(idList, positionInfoList, siteId);
        }
        return positionInfoList;
    }

    @Override
    public List<PositionInfoListVO> listPositionTypeByCompanyId(String companyId, String siteId) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("type", 2)
                .andEqualTo("level", 2)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        example.orderBy("gmtCreate");

        List<PositionInfoListVO> list = getVoListByDoList(positionInfoDAO.selectByExample(example));
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        list.forEach(
                positionType -> {
                    // 获取岗位类型下岗位个数
                    List<PositionInfoListVO> positionInfoList = listChildPositionByParent(positionType.getId(), 1, siteId);
                    positionType.setChildCount(CollectionUtils.isEmpty(positionInfoList) ? 0 : positionInfoList.size());
                }
        );
        return list;
    }

    @Override
    public List<PositionInfoListVO> listChildPositionByParent(String parentId, int type, String siteId) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("parentId", parentId)
                .andEqualTo("type", type)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);

        return getVoListByDoList(positionInfoDAO.selectByExample(example));
    }

    /**
     * 递归获取所有子分类，单层的
     *
     * @param positionList     部门id集合
     * @param positionInfoList 所有部门
     * @param siteId           站点id
     */
    private void getAllChildList(List<String> positionList, List<PositionInfoDO> positionInfoList, String siteId) {
        if (CollectionUtils.isEmpty(positionList)) {
            return;
        }
        if (positionInfoList == null) {
            positionInfoList = new ArrayList<>();
        }
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andIn("parentId", positionList)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        List<PositionInfoDO> list = positionInfoDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            positionInfoList.addAll(list);
            getAllChildList(list.stream().map(PositionInfoDO::getId).collect(Collectors.toList()), positionInfoList, siteId);
        }
    }

    @Override
    public List<PositionInfoDO> listByName(String name, String companyId, String siteId) {
        Example example = new Example(PositionInfoDO.class);
        example.and()
                .andEqualTo("name", name)
                .andEqualTo("companyId", companyId)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        return positionInfoDAO.selectByExample(example);
    }

    @Override
    public Map<String, String> getPositionIdAndNameMapByCompany(String companyId, String siteId) {
        List<PositionInfoDO> positionInfoList = listByCompanyId(companyId, siteId);
        if (CollectionUtils.isEmpty(positionInfoList)) {
            return new HashMap<>();
        }
        return positionInfoList.parallelStream().collect(
                Collectors.toMap(
                        PositionInfoDO::getId,
                        PositionInfoDO::getName
                )
        );
    }

    @Override
    public List<PositionInfoDO> selectByIdList(List<String> positionInfoIdList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(positionInfoIdList)) {
            return new ArrayList<>();
        }
        Example example = new Example(PositionInfoDO.class);
        example.and().andIn("id", positionInfoIdList)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        return positionInfoDAO.selectByExample(example);
    }
}




